<template>
  <view class="uni-collapse-item">
    <!-- onClick(!isOpen) -->
    <view
      class="uni-collapse-item__title" :class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}"
      @click="onClick(!isOpen)">
      <view class="uni-collapse-item__title-wrap">
        <slot name="title">
          <view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
            <image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
            <text class="uni-collapse-item__title-text">
              {{ title }}
            </text>
          </view>
        </slot>
      </view>
      <view 
        :class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
        class="uni-collapse-item__title-arrow">
        <uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="bottom" />
      </view>
    </view>
    <view
      class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
      :style="{height: (isOpen?height:0) +'px'}">
      <view
        :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
        :class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
        <slot />
      </view>
    </view>
  </view>
</template>

<script>
	// #ifdef APP-NVUE
  const dom = weex.requireModule('dom')
  // #endif
  /**
   * CollapseItem 折叠面板子组件
   * @description 折叠面板子组件
   * @property {String} title 标题文字
   * @property {String} thumb 标题左侧缩略图
   * @property {String} name 唯一标志符
   * @property {Boolean} open = [true|false] 是否展开组件
   * @property {Boolean} titleBorder = [true|false] 是否显示标题分隔线
   * @property {Boolean} border = [true|false] 是否显示分隔线
   * @property {Boolean} disabled = [true|false] 是否展开面板
   * @property {Boolean} showAnimation = [true|false] 开启动画
   * @property {Boolean} showArrow = [true|false] 是否显示右侧箭头
   */
  export default {
    name: 'UniCollapseItem',
    props: {
      // 列表标题
      title: {
        type: String,
        default: ''
      },
      name: {
        type: [Number, String],
        default: ''
      },
      // 是否禁用
      disabled: {
        type: Boolean,
        default: false
      },
      // #ifdef APP-PLUS
      // 是否显示动画,app 端默认不开启动画，卡顿严重
      showAnimation: {
        type: Boolean,
        default: false
      },
      // #endif
      // #ifndef APP-PLUS
      // 是否显示动画
      showAnimation: {
        type: Boolean,
        default: true
      },
      // #endif
      // 是否展开
      open: {
        type: Boolean,
        default: false
      },
      // 缩略图
      thumb: {
        type: String,
        default: ''
      },
      // 标题分隔线显示类型
      titleBorder: {
        type: String,
        default: 'auto'
      },
      border: {
        type: Boolean,
        default: true
      },
      showArrow: {
        type: Boolean,
        default: true
      }
    },
    data() {
      // TODO 随机生生元素ID，解决百度小程序获取同一个元素位置信息的bug
      const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
      return {
        isOpen: false,
        isheight: null,
        height: 0,
        elId,
        nameSync: 0
      }
    },
    watch: {
      open(val) {
        this.isOpen = val
        this.onClick(val, 'init')
      }
    },
    updated(e) {
      this.$nextTick(() => {
        this.init(true)
      })
    },
    created() {
      this.collapse = this.getCollapse()
      this.oldHeight = 0
      this.onClick(this.open, 'init')
    },
    // #ifndef VUE3
    // TODO vue2
    destroyed() {
      if (this.__isUnmounted) return
      this.uninstall()
    },
    // #endif
    // #ifdef VUE3
    // TODO vue3
    unmounted() {
      this.__isUnmounted = true
      this.uninstall()
    },
    // #endif
    mounted() {
      if (!this.collapse) return
      if (this.name !== '') {
        this.nameSync = this.name
      } else {
        this.nameSync = this.collapse.childrens.length + ''
      }
      if (this.collapse.names.indexOf(this.nameSync) === -1) {
        this.collapse.names.push(this.nameSync)
      } else {
        console.warn(`name 值 ${this.nameSync} 重复`);
      }
      if (this.collapse.childrens.indexOf(this) === -1) {
        this.collapse.childrens.push(this)
      }
      this.init()
    },
    methods: {
      calculateheight() {
        this.$nextTick(() => {
          setTimeout(() => {
            console.log('collapse-init')
            this.init(true)
          }, 200)
        })
      },
      init(type) {
        // #ifndef APP-NVUE
        this.getCollapseHeight(type)
        // #endif
        // #ifdef APP-NVUE
        this.getNvueHwight(type)
        // #endif
      },
      uninstall() {
        if (this.collapse) {
          this.collapse.childrens.forEach((item, index) => {
            if (item === this) {
              this.collapse.childrens.splice(index, 1)
            }
          })
          this.collapse.names.forEach((item, index) => {
            if (item === this.nameSync) {
              this.collapse.names.splice(index, 1)
            }
          })
        }
      },
      onClick(isOpen, type) {
        if (this.disabled) return
        this.isOpen = isOpen
        if (this.isOpen && this.collapse) {
          this.collapse.setAccordion(this)
        }
        if (type !== 'init') {
          this.collapse.onChange(isOpen, this)
        }
      },
      getCollapseHeight(type, index = 0) {
        const views = uni.createSelectorQuery().in(this)
        views
          .select(`#${this.elId}`)
          .fields({
            size: true
          }, data => {
            // TODO 百度中可能获取不到节点信息 ，需要循环获取
            if (index >= 10) return
            if (!data) {
              index++
              this.getCollapseHeight(false, index)
              return
            }
            // #ifdef APP-NVUE
            this.height = data.height + 1
            // #endif
            // #ifndef APP-NVUE
            this.height = data.height
            // #endif
            this.isheight = true
            if (type) return
            this.onClick(this.isOpen, 'init')
          })
          .exec()
      },
      getNvueHwight(type) {
        const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
          if (option && option.result && option.size) {
            // #ifdef APP-NVUE
            this.height = option.size.height + 1
            // #endif
            // #ifndef APP-NVUE
            this.height = option.size.height
            // #endif
            this.isheight = true
            if (type) return
            this.onClick(this.open, 'init')
          }
        })
      },
      /**
       * 获取父元素实例
       */
      getCollapse(name = 'uniCollapse') {
        let parent = this.$parent;
        let parentName = parent.$options.name;
        while (parentName !== name) {
          parent = parent.$parent;
          if (!parent) return false;
          parentName = parent.$options.name;
        }
        return parent;
      }
    }
  }
</script>

<style lang="scss">
	.uni-collapse-item {
		/* #ifndef APP-NVUE */
		box-sizing: border-box;

		/* #endif */
		&__title {
			/* #ifndef APP-NVUE */
			display: flex;
			width: 100%;
			box-sizing: border-box;
			/* #endif */
			flex-direction: row;
			align-items: center;
			transition: border-bottom-color .3s;

			// transition-property: border-bottom-color;
			// transition-duration: 5s;
			&-wrap {
				width: 100%;
				flex: 1;

			}

			&-box {
				padding: 0 15px;
				/* #ifndef APP-NVUE */
				display: flex;
				width: 100%;
				box-sizing: border-box;
				/* #endif */
				flex-direction: row;
				justify-content: space-between;
				align-items: center;
				height: 48px;
				line-height: 48px;
				background-color: #fff;
				color: #303133;
				font-size: 13px;
				font-weight: 500;
				/* #ifdef H5 */
				cursor: pointer;
				outline: none;

				/* #endif */
				&.is-disabled {
					.uni-collapse-item__title-text {
						color: #999;
					}
				}

			}

			&.uni-collapse-item-border {
				border-bottom: 1px solid #ebeef5;
			}

			&.is-open {
				border-bottom-color: transparent;
			}

			&-img {
				height: 22px;
				width: 22px;
				margin-right: 10px;
			}

			&-text {
				flex: 1;
				font-size: 14px;
				/* #ifndef APP-NVUE */
				white-space: nowrap;
				color: inherit;
				/* #endif */
				/* #ifdef APP-NVUE */
				lines: 1;
				/* #endif */
				overflow: hidden;
				text-overflow: ellipsis;
			}

			&-arrow {
				/* #ifndef APP-NVUE */
				display: flex;
				box-sizing: border-box;
				/* #endif */
				align-items: center;
				justify-content: center;
				width: 20px;
				height: 20px;
				margin-right: 10px;
				transform: rotate(0deg);

				&-active {
					transform: rotate(-180deg);
				}
			}


		}

		&__wrap {
			/* #ifndef APP-NVUE */
			will-change: height;
			box-sizing: border-box;
			/* #endif */
			background-color: #fff;
			overflow: hidden;
			position: relative;
			height: 0;

			&.is--transition {
				// transition: all 0.3s;
				transition-property: height, border-bottom-width;
				transition-duration: 0.3s;
				/* #ifndef APP-NVUE */
				will-change: height;
				/* #endif */
			}



			&-content {
				position: absolute;
				font-size: 13px;
				color: #303133;
				// transition: height 0.3s;
				border-bottom-color: transparent;
				border-bottom-style: solid;
				border-bottom-width: 0;

				&.uni-collapse-item--border {
					border-bottom-width: 1px;
					border-bottom-color: red;
					border-bottom-color: #ebeef5;
				}

				&.open {
					position: relative;
				}
			}
		}

		&--animation {
			transition-property: transform;
			transition-duration: 0.3s;
			transition-timing-function: ease;
		}

	}
</style>
